package ca.jerg.data;

import java.io.*;
import java.util.*;

public class ErgData implements IErgPoint,IErgData
{
	public static void main( String args[] ) throws IOException
	{		
		ErgData ed = new ErgData();
		BufferedReader br = new BufferedReader(new FileReader("test2.erg"));
		ed.read(br);
		ed.write();
		System.out.println("++");
				
		System.out.println(ed.remove(10.0,20));
		ed.write();
	}
	
	/**
	 * Create a blank data set.  The data set can be
	 * built by either reading from a file or by using
	 * any of the insert methods.
	 */
	public ErgData()
	{
		data = new ArrayList<ErgPoint>();
		Edited = false;
	}
	
	
	public boolean insert( ErgPoint newPoint )
	{
		Edited = true;
		
		return data.add(newPoint);
	}

	
	public boolean insertAt( double time, ErgPoint newPoint )
	{            
		Edited = true;
		
		int index = 0;
        Iterator i = data.iterator();
        
        // scan through current data
        while ( i.hasNext() )
        {
        	ErgPoint ep = (ErgPoint)i.next();
        	if ( ep.getTime() > time )
        	{
        		// add the new point
        		data.add(index,newPoint);
        		
        		return true;
        	}
        	
        	index++;
        }            
		
        // all current times are less then the new time or there
        // are no data points in the list, either way just add
        // the new data point to the end of the list
		return insert(newPoint);
	}
	
	
	public boolean insert( ArrayList<ErgPoint> newData )
	{		
		Edited = true;
		
		return data.addAll(newData);
	}

	
	public boolean insertAt( double time, ArrayList<ErgPoint> newData )
	{
		Edited = true;
		
		int index = 0;
		int insertIndex = -1;
        Iterator i = data.iterator();
                
        // scan through current data
        while ( i.hasNext() )
        {
        	ErgPoint ep = (ErgPoint)i.next();
        	if ( ep.getTime() > time )
        	{        	
        		// remember where to insert the new data points
        		insertIndex = index;
        		        		
                // get the last time of the new data points
                ErgPoint last = (ErgPoint)newData.get(newData.size() - 1);

                while ( (ep.getTime() < last.getTime()) && (i.hasNext()) )
                {
                	i.remove();
                	ep = (ErgPoint)i.next();
                }

                break;
        	}
        	
        	index++;
        }            
		
        if ( insertIndex != -1 )
        	return data.addAll(insertIndex,newData);
        
        // all current times are less then the first new time or there
        // are no data points in the list, either way just add
        // the new data points to the end of the list
		return insert(newData);
	}

	
	public boolean remove( double time )
	{
		Edited = true;
		
		Iterator i = data.iterator();
		
		while ( i.hasNext() )
		{
			ErgPoint ep = (ErgPoint)i.next();
			if ( ep.getTime() == time )
				i.remove();				
		}
		
		return true;
	}

	
	public boolean remove( double time, int number )
	{		
		Iterator i = data.iterator();
		
		while ( i.hasNext() )
		{
			ErgPoint ep = (ErgPoint)i.next();
			if ( ep.getTime() == time )
			{
				for ( int idx=0; idx<number; idx++ )
				{
					i.remove();
					if ( (idx < number) && (i.hasNext() == false) )
						return false;
					
					i.next();
				}
			}
		}
		
		Edited = true;
		return true;
	}
	
	public boolean removeAll()
	{
		return data.removeAll(data);
	}
	
	public int read( BufferedReader in )
	{		
		while ( true )
		{
			ErgPoint ep = new ErgPoint();
			switch ( ep.read(in) )
			{
				case 0:				// normal read
					data.add(ep);
					break;
				
				case 1:				// read data error
					System.err.println(ERG_DATA_STR + "Read error");
					return 1;
					
				case 2:				// end of file
					return 0;					
			}
		}
	}

	
	public void write()
	{
        Iterator i = data.iterator();
        while ( i.hasNext() )
        {
        	ErgPoint ep = (ErgPoint)i.next();
        	ep.write();
        }            
	}

	
	public boolean write( BufferedWriter out )
	{
        Iterator i = data.iterator();
        while ( i.hasNext() )
        {
        	ErgPoint ep = (ErgPoint)i.next();
        	if ( ep.write(out) == false )
        	{
        		System.err.println(ERG_DATA_STR + "Write error");
        		return false;
        	}
        	
        	try
        	{
        		out.newLine();
        	}
        	catch ( IOException ioe )
        	{
        		System.err.println(ERG_DATA_STR + "File write error");
        		return false;
        	}
        }		

		Edited = false;
		return true;
	}

	public ArrayList<ErgPoint> getData()
	{
		return data;
	}
	
	public ErgPoint getLastPoint() throws IndexOutOfBoundsException
	{
		return data.get(data.size() - 1);
	}

	public boolean isEdited()
	{
		return Edited;
	}

	public void setEdited( boolean beenEdited )
	{
		this.Edited = beenEdited;
	}
	

	private ArrayList<ErgPoint> data;
	private boolean Edited;
	
	private final String ERG_DATA_STR = "ErgData: ";
}
